Skip to content

feat: UI Sidebar + Chat Overhaul#195

Open
vaststudios wants to merge 2 commits into21st-dev:mainfrom
Vast-Studios:feat/chat-font-size
Open

feat: UI Sidebar + Chat Overhaul#195
vaststudios wants to merge 2 commits into21st-dev:mainfrom
Vast-Studios:feat/chat-font-size

Conversation

@vaststudios
Copy link
Copy Markdown

@vaststudios vaststudios commented Apr 6, 2026

Summary

This PR brings together a batch of improvements spanning font size customization, a major sidebar architecture rework, TypeScript strictness fixes, and various UI polish across the desktop app.

What's New

1. Configurable Chat Font Size (12–16px)

Adds a user preference to scale text in both assistant responses and user message bubbles.

How it works:

  • New chatFontSizeAtom persisted to localStorage (default 14px — matches previous text-sm)
  • Converted the sm markdown size variant from rem-based (text-sm) to em-based (text-[1em]) — rem always resolves relative to root, ignoring parent fontSize. em inherits from parent, enabling dynamic scaling.
  • baseFontSize prop threaded through MemoizedMarkdownMemoizedMarkdownBlockChatMarkdownRenderer with inline style={{ fontSize }} override on the prose-sm wrapper
  • User message bubbles get the same fontSize via style prop
  • All custom memo comparisons updated to include baseFontSize

Files: atoms/index.ts, chat-markdown-renderer.tsx, memoized-text-part.tsx, agent-user-message-bubble.tsx, agents-appearance-tab.tsx

2. Configurable Terminal Font Size (10–24px)

Adds a user preference for terminal text size with dynamic line height scaling.

How it works:

  • New terminalFontSizeAtom persisted to localStorage (default 13px)
  • getTerminalLineHeight() scales line-height per font size (1.3 for ≤11px, up to 1.45 for >16px) so small fonts don't feel over-spaced
  • Font size passed into createTerminalInstance() options at creation time
  • Live update via useEffect that sets xterm.options.fontSize + lineHeight and refits — no terminal recreation needed

Files: terminal/atoms.ts, terminal/config.ts, terminal/helpers.ts, terminal/terminal.tsx

3. Unified Sidebar Architecture

Replaces the separate sub-chats sidebar with a unified workspace tree in the main sidebar.

Key changes:

  • Sidebar rework (agents-sidebar.tsx, +1430/-583 lines): Workspace tree with collapsible sections, expanded state tracking via expandedWorkspaceIdsAtom, sort popover, and Tabler icons
  • Sub-chats sidebar removed from agents-content.tsx — no more ResizableSidebar + AgentsSubChatsSidebar wrapper
  • Header controls gutted (agents-header-controls.tsx): Sidebar toggle moved to a floating animated button in agents-layout.tsx using AnimatePresence + motion.button
  • Sub-chat selector tabs polished (sub-chat-selector.tsx): Rounded-full pill style, refined active/inactive colors, removed the "open sidebar" button
  • Layout updates (agents-layout.tsx): Sidebar max width increased to 400px, animation duration set to 0.2s, floating toggle button with macOS traffic light offset
  • New sidebar state atoms: expandedWorkspaceIdsAtom, agentsSubChatUnseenChangesAtom

4. Workspace Accent Colors

  • New accentColor column on chats table (hex string, nullable)
  • DB migration 0008_steep_warlock.sql
  • New chats.updateColor tRPC mutation

5. TypeScript Strictness Fixes

Cleaned up type safety issues across the codebase:

  • as const assertions on behavior literals in claude router ("deny" as const, "allow" as const)
  • as unknown as UIMessageChunk double-cast for custom extension types with explanatory comments
  • Typed finalEnv as Record<string, string> with comment explaining why
  • Fixed mock hook return types (useSearchParams, useRouter, useClerk, useCombinedAuth)
  • Proper nullable types on DiffSidebarRendererProps (prUrl?: string | null, isFullscreen: boolean | null)
  • Null coalescing on sandboxId, repository, isFullscreen props
  • @ts-nocheck on WIP credential-manager.ts (dependencies not yet created)
  • Import path fixes: .ts → bare extensions in credential-manager imports
  • Typed callback params in SourceCredentialManager.authenticate()

6. Other Improvements

  • Claude router: Removed emitSdkMessageUuid option from transformer config
  • Git watcher: Minor adjustments
  • Codex router: Additions
  • Plugins router: Fix
  • Mock API / Remote API / Remote tRPC: Small fixes
  • Agent components: Minor type/import cleanups across agent-chat-card, agent-model-selector, agents-quick-switch-dialog, work-mode-selector, text-selection-context, agent-dialog, agents-custom-agents-tab, agents-mentions-editor

Files Changed

52 files, +1,969 insertions, -604 deletions

Test Plan

  • Chat font size: Settings > Appearance > change "Chat font size" → assistant messages and user bubbles resize. Default (14px) looks identical to current behavior. Headings scale proportionally.
  • Terminal font size: Settings > Appearance > change "Terminal font size" → terminal updates live without restart. Line height scales appropriately.
  • Sidebar: Workspace tree renders, sections expand/collapse, unseen indicators work, sort popover functions, floating toggle button appears when sidebar is closed.
  • Accent colors: Right-click workspace → set accent color → persists across reload.
  • Sub-chat tabs: Pill-shaped tabs render correctly, active/inactive states look good, no "open sidebar" button in tab bar.
  • TypeScript: npx tsc --noEmit passes cleanly.
  • DB migration: Fresh install applies migration 0008 without error.

🤖 Generated with Claude Code

vaststudios and others added 2 commits April 6, 2026 14:06
Add a chat font size preference (12–16px, default 14px) that scales
both assistant responses and user message bubbles.

- Add chatFontSizeAtom persisted to localStorage
- Convert sm sizeStyles from rem-based (text-sm) to em-based (text-[1em])
  so text inherits from parent fontSize instead of being root-relative
- Pass baseFontSize prop through MemoizedMarkdown/ChatMarkdownRenderer
  with inline style override for prose-sm's rem-based font-size
- Apply font size to user message bubbles via style prop
- Add Chat Font Size + Terminal Font Size selectors in Appearance settings

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…, and improvements

Includes all recent development work:
- Chat font size setting (12-16px) in Appearance settings
- Sidebar rework with workspace tree and expanded state
- Terminal font size and config improvements
- Claude integration updates (transform, credential manager)
- Agent UI improvements (diff view, tool registry, header controls)
- Sub-chat selector and content updates
- Layout and mentions system refinements
- DB schema migration (0008)
- Various bug fixes and polish

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@vaststudios vaststudios changed the title feat: add configurable chat font size setting feat: chat font size, sidebar rework, terminal font size, TypeScript fixes & UI polish Apr 6, 2026
@vaststudios vaststudios changed the title feat: chat font size, sidebar rework, terminal font size, TypeScript fixes & UI polish feat: UI Sidebar + Chat Overhaul Apr 6, 2026
@vaststudios
Copy link
Copy Markdown
Author

Hey! Here's a walkthrough of what this PR covers — happy to discuss any of it.

What changed

Sidebar Architecture Rework

The biggest change here. Replaced the separate sub-chats sidebar (AgentsSubChatsSidebar + ResizableSidebar wrapper in agents-content.tsx) with a unified workspace tree built directly into the main sidebar (agents-sidebar.tsx). This means:

  • Workspaces are now collapsible tree sections in the main sidebar with expand/collapse state persisted via expandedWorkspaceIdsAtom
  • The "open sidebar" button was removed from the sub-chat tab bar
  • AgentsHeaderControls is now a no-op shell (kept to avoid breaking imports) — the sidebar toggle is now a floating animated button in agents-layout.tsx
  • Sidebar max width bumped from 300→400px, animation duration set to 0.2s
  • Added Tabler icons, sort popover, and Skeleton loading states

Chat Font Size (new setting)

Users can now pick 12–16px for chat text in Settings > Appearance. The tricky part was that Tailwind's text-sm uses rem units (always 14px relative to root), so I switched the sm size variant in chat-markdown-renderer.tsx from text-sm to text-[1em] — this makes text inherit from the parent's fontSize set via inline style. Default 14px matches the old behavior exactly.

Terminal Font Size (new setting)

Same idea for the terminal — 10–24px range, default 13px. Added getTerminalLineHeight() that scales line-height per font size so small fonts don't feel over-spaced. Updates live via xterm options + refit, no terminal recreation needed.

Workspace Accent Colors

New accentColor text column on chats table (migration 0008) + chats.updateColor tRPC mutation. Lets users visually differentiate workspaces.

TypeScript Fixes

A bunch of strictness cleanups:

  • as const on behavior literals in the claude router
  • as unknown as UIMessageChunk double-cast for custom event types (with comments explaining why)
  • Proper nullable types on diff sidebar props
  • Fixed mock hook return types (useSearchParams, useRouter, etc.)
  • @ts-nocheck on credential-manager.ts since its dependencies don't exist yet

Sub-chat Tab Polish

Tabs are now pill-shaped (rounded-full), refined active/inactive colors with bg-foreground/[0.06] and transparent borders, slightly wider padding.

Known considerations

  • credential-manager.ts has @ts-nocheck — it's a WIP file waiting on auth dependencies
  • AgentsHeaderControls returns null now — it's kept as a shell. Can be fully removed once all import sites are cleaned up
  • The sidebar rework is substantial (~1400 lines changed in agents-sidebar.tsx), so worth a careful review there

If anything looks off or needs adjusting, feel free to reach out — I'm happy to iterate on this. You can ping me directly on the PR or via GitHub.

— Dennis

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant